package com.scrm.exam.utils;

import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.function.BiConsumer;

/**
 * 批量小助手
 */
@Slf4j
@Component
public class BatchHelper {
    @Resource
    private SqlSessionFactory sqlSessionFactory;
    /**
     * 1000次提交一次事务
     */
    private static final int COMMIT_NUM = 1000;


    /**
     * 批量更新或者插入数据
     */
    public <M, T> void batchInsertOrUpdate(List<T> dataList, Class<M> classzz, BiConsumer<M, T> action) {
        long startTime = System.currentTimeMillis();
        if (CollectionUtil.isEmpty(dataList)) {
            log.info("batchInsertOrUpdate data is null !");
            return;
        }
        SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
        try {
            M mapper = session.getMapper(classzz);
            int count = 0;
            for (T t : dataList) {
                action.accept(mapper, t);
                count++;
                if (count >= COMMIT_NUM) {
                    session.commit();
                    session.clearCache();
                    log.info("批量小助手插入更新时间：{}", System.currentTimeMillis() - startTime);
                }
            }
            session.commit();
            session.clearCache();
            log.info("批量小助手插入更新时间：{}", System.currentTimeMillis() - startTime);
        } catch (Exception e) {
            log.error("batchInsertOrUpdate is exception classz:{},异常信息:{}", classzz.getName(), e);
            session.rollback();
        } finally {
            session.close();
        }
    }


    /**
     * 批量更新或者插入数据
     */
    public <M, T> void batchInsertOrUpdate(List<T> dataList, Class<M> classzz, BiConsumer<M, T> action,boolean needRollBack) {
        long startTime = System.currentTimeMillis();
        if (CollectionUtil.isEmpty(dataList)) {
            log.info("batchInsertOrUpdate data is null !");
            return;
        }
        SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
        try {
            M mapper = session.getMapper(classzz);
            int count = 0;
            for (T t : dataList) {
                action.accept(mapper, t);
                count++;
                if (count >= COMMIT_NUM) {
                    session.commit();
                    session.clearCache();
                    log.info("批量小助手插入更新时间：{}", System.currentTimeMillis() - startTime);
                }
            }
            session.commit();
            session.clearCache();
            log.info("批量小助手插入更新时间：{}", System.currentTimeMillis() - startTime);
        } catch (Exception e) {
            log.error("batchInsertOrUpdate is exception classz:{},异常信息:{}", classzz.getName(), e);
            if (needRollBack) {
                session.rollback();
            }
        } finally {
            session.close();
        }
    }
}
